package com.firmail.cloud.aspect;

import com.firmail.exception.cloud.NoPermissionException;
import com.firmail.exception.cloud.ParamsErrorException;
import com.firmail.exception.cloud.ParamsInvalidException;
import com.firmail.exception.type.cloud.CloudExceptionType;
import com.firmail.mock.common.model.ReturnData;
import com.firmail.mock.util.GsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
@Slf4j
public class CloudAspect {


    private ThreadLocal<Long> timeConsuming = new ThreadLocal<>();
    private ThreadLocal<String> method = new ThreadLocal<>();

    @Pointcut("execution(* com.firmail.cloud.*.service.*.*(..))")
    public void pointcut() {

    }

    @Before(value = "pointcut()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            timeConsuming.set(System.nanoTime());
            method.set(joinPoint.getSignature().getName());

            StringBuffer buffer;
            if (joinPoint.getArgs() != null) {
                buffer = new StringBuffer();
                for (Object obj : joinPoint.getArgs()) {
                    buffer.append(GsonUtils.toJson(obj)).append("|");
                }
                log.info("==》【cloud service】开始：方法： {}, 其请求参数：{}", joinPoint.getSignature(), buffer);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @AfterReturning(returning = "ret", pointcut = "pointcut()")
    public void doAfterReturning(Object ret) {
        try {
            //if (log.isDebugEnabled()) {
            log.info("==》【cloud service】结束：总共耗时：{}， 返回结果：{}",
                    String.format("%d ms", TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - timeConsuming.get())),
                    GsonUtils.toJson(ret));
            //}
//        } catch (Exception e) {
//            log.error(e.getMessage());
        } finally {
            timeConsuming.remove();
        }
        if (ret == null) {
            String m = null;
            try {
                m = method.get();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                method.remove();
            }
            throw new RuntimeException("模块没有响应为空.请求的目标： " + m);
        }
        if (ret instanceof ReturnData<?>) {
            ReturnData<?> data = (ReturnData<?>) ret;
            //if (data != null) {
            CloudExceptionType type = CloudExceptionType.getByCode(data.getStatus());
            if (type != null)
                switch (type) {
                    case CLOUD_NO_PERMISSION_EXCEPTION:
                        throw new NoPermissionException(type);
                    case CLOUD_PARAMS_ERROR_EXCEPTION:
                        throw new ParamsErrorException(type);
                    case CLOUD_PARAMS_INVALID_EXCEPTION:
                        throw new ParamsInvalidException(type);
                    case CLOUD_SYSTEM_EXCEPTION:
                        throw new RuntimeException(data.getMessage());
                    default:
                        break;
                }
            //}
        } else {
            log.warn("==》模块调用返回为空.@AfterReturning-> {}" + CloudAspect.class.getName());
        }
    }
}
